package org.jwebuilder.event;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.util.JSONUtils;

public class EventResult
{
	public enum ResultType
	{
		General,
		Redirect,
		Forward,
		ForceRedirect,
		ForceForward,
		BreakChain
	}

	private ResultType resultType;
	private String targetUrl;
	private boolean ajax = false;
	private Object result;

	public ResultType getResultType()
	{
		return resultType;
	}
	public void setResultType(ResultType resultType)
	{
		this.resultType = resultType;
	}
	public String getTargetUrl()
	{
		return targetUrl;
	}
	public void setTargetUrl(String targetUrl)
	{
		this.targetUrl = targetUrl;
	}
	
	public boolean isAjax()
	{
		return ajax;
	}
	public void setAjax(boolean ajax)
	{
		this.ajax = ajax;
	}
	
	public Object getResult()
	{
		return result;
	}
	public void setResult(Object result)
	{
		this.result = result;
	}
	
	public EventResult(ResultType resultType)
	{
		this.resultType = resultType;
	}
	public EventResult(ResultType resultType, Object result)
	{
		this.resultType = resultType;
		this.result = result;
	}
	public EventResult(ResultType resultType, String targetUrl)
	{
		this.resultType = resultType;
		this.targetUrl = targetUrl;
	}
	public EventResult(ResultType resultType, boolean ajax)
	{
		this.resultType = resultType;
		this.ajax = ajax;
	}
	public EventResult(ResultType resultType, String targetUrl, boolean ajax)
	{
		this.resultType = resultType;
		this.targetUrl = targetUrl;
		this.ajax = ajax;
	}
	public EventResult(ResultType resultType, Object result, boolean ajax)
	{
		this.resultType = resultType;
		this.result = result;
		this.ajax = ajax;
	}

	public static EventResult general()
	{
		return new EventResult(ResultType.General);
	}
	
	public static EventResult ajaxGeneral()
	{
		return new EventResult(ResultType.General, true);
	}
	
	public static EventResult general(Object result)
	{
		return new EventResult(ResultType.General, result);
	}
	
	public static EventResult ajaxGeneral(Object result)
	{
		return new EventResult(ResultType.General, result, true);
	}
	
	public static EventResult redirect(String targetUrl)
	{
		return new EventResult(ResultType.Redirect, targetUrl);
	}
	
	public static EventResult ajaxRedirect(String targetUrl)
	{
		return new EventResult(ResultType.Redirect, targetUrl, true);
	}

	public static EventResult forward(String targetUrl)
	{
		return new EventResult(ResultType.Forward, targetUrl);
	}

	public static EventResult forceRedirect(String targetUrl)
	{
		return new EventResult(ResultType.ForceRedirect, targetUrl);
	}
	
	public static EventResult ajaxForceRedirect(String targetUrl)
	{
		return new EventResult(ResultType.ForceRedirect, targetUrl, true);
	}

	public static EventResult forceForward(String targetUrl)
	{
		return new EventResult(ResultType.ForceForward, targetUrl);
	}

	public static EventResult breakChain()
	{
		return new EventResult(ResultType.BreakChain);
	}
	
	public String process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
	{
		if(getResultType() == ResultType.General)
		{
			if(isAjax())
			{
				Object responseResult = getResult();
				if(responseResult != null)
				{
					if(JSONUtils.isArray(responseResult))
					{
						return JSONArray.fromObject(responseResult).toString();
					}
					else
					{
						return JSONObject.fromObject(responseResult).toString();
					}
				}
				else
				{
					return null;
				}
			}
			else
			{
				return null;
			}
		}
		else if(getResultType() == ResultType.Redirect || getResultType() == ResultType.ForceRedirect)
		{
			if(isAjax())
			{
				return getTargetUrl();
			}
			else
			{
				response.sendRedirect(getTargetUrl());
				return null;
			}
		}
		else if(getResultType() == ResultType.Forward || getResultType() == ResultType.ForceForward)
		{
			request.getRequestDispatcher(getTargetUrl()).forward(request, response);
			return null;
		}
		else
		{
			return null;
		}
	}
}